package com.nowcoder.community.controller;

import com.nowcoder.community.entity.Message;
import com.nowcoder.community.entity.Page;
import com.nowcoder.community.entity.User;
import com.nowcoder.community.service.MessageService;
import com.nowcoder.community.service.UserService;
import com.nowcoder.community.util.CommunityUtil;
import com.nowcoder.community.util.HostHolder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.*;

@Controller
public class MessageController {
    @Autowired
    private MessageService messageService;

    @Autowired
    private HostHolder hostHolder;

    @Autowired
    private UserService userService;

    /**
     * 私信列表
     * @param model
     * @param page
     * @return
     */
    @GetMapping("/letter/list")
    public String getLetterList(Model model, Page page){ //为了向页面传数据，需要申明一个Model;为了支持分页加上page这个组件
        User user = hostHolder.getUser();
        //为了实现查询，需要注入Service;又因为要查询当前用户的私信，因此需要注入Hostholder

        //设置分页信息
        page.setLimit(5);
        //设置访问路径为当前的路径
        page.setPath("/letter/list");
        //设置一共有多少条回话数据，得查
        page.setRows(messageService.findConversationCount(user.getId())); //需要传入userId，通过hostholder获得，后面还会用到，先在前面传入

        //查询回话列表
        List<Message> conversationList = messageService.findConversations(
                user.getId(), page.getOffset(), page.getLimit());
        //页面包含额外的内容，把额外的内容查到，然后进行包装
        //声明一个集合，里面是Map，把多个数据都存进map里
        List<Map<String,Object>> conversations = new ArrayList<>();
        //遍历列表构造Map，如果不等于null，就去遍历
        if(conversationList != null){
            for (Message message : conversationList) {
                //每次遍历需要构造一个Map重构数据
                Map<String,Object> map = new HashMap<>();
                //首先把message先存进去,名字和业务相匹配
                map.put("conversation", message);
                //未读消息数量(因为通讯双方未读消息数量可能不同，因此需要传入userId)
                map.put("unreadCount",messageService.findLetterUnreadCount(user.getId(), message.getConversationId()));
                //私信数量(因为通讯双方的私信数量是一样的，因此不需要传入userId)
                map.put("letterCount",messageService.findLetterCount(message.getConversationId()));
                //发送消息用户头像，显示当前用户相对的那个人的用户头像(有可能最新消息是它发给我的，也可能是我发给它的)
                int targetId = user.getId() == message.getFromId() ? message.getToId() : message.getFromId();
                //需要查询用户信息，注入UserService
                map.put("target",userService.findUserById(targetId));

                //最终得到的map放入列表中
                conversations.add(map);
            }
            //将集合中的数据放入Model传给模版
            model.addAttribute("conversations",conversations);

            //查询未读消息数量
            int letterUnreadCount = messageService.findLetterUnreadCount(user.getId(),null);
            model.addAttribute("letterUnreadCount",letterUnreadCount);
        }
        //最后返回模版路径
        return "/site/letter";
    }

    /**
     * 私信详情
     */
    @GetMapping("/letter/detail/{conversationId}")
    public String getLetterDetail(@PathVariable("conversationId") String conversationId,Page page,Model model){  //获取路径参数；显示详情，显示多页，也要支持分页;向页面传输局，声明Model
        //设置分页信息
        //设置每页显示条数
        page.setLimit(5);
        //设置路径
        page.setPath("/letter/detail/"+conversationId);
        //查私信总行数
        page.setRows(messageService.findLetterCount(conversationId));

        //进行分页查询获取私信列表
        List<Message> letterList = messageService.findLetters(conversationId, page.getOffset(), page.getLimit());
        //页面包含额外的内容，把额外的内容查到，然后进行包装
        List<Map<String,Object>> letters = new ArrayList<>();
        //遍历列表构造Map，如果不等于null，就去遍历
        if(letterList != null){
            for (Message message : letterList) {
                //实例化map，封装数据
                Map<String,Object> map = new HashMap<>();
                //把私信放进去,取名为letter和业务保持一致
                map.put("letter",message);
                //把fromId变换为fromUser,做一次查询即可
                map.put("fromUser",userService.findUserById(message.getFromId()));

                //把map放入集合里
                letters.add(map);
            }
        }
        //把集合发送给模版
        model.addAttribute("letters",letters);

        //查询私信目标，并发送给模版
        model.addAttribute("target",getLetterTraget(conversationId));

        //把私信列表中未读的消息提取出来设为已读
        List<Integer> ids = getLetterIds(letterList);
        if (!ids.isEmpty()) {
            messageService.readMessage(ids);
        }

        //数据处理完后，返回模版
        return "/site/letter-detail";
    }

    //获取未读的消息
    private List<Integer> getLetterIds(List<Message> letterList){ //传入私信列表，从中筛选
        //获取未读消息id
        List<Integer> ids = new ArrayList<>();

        if (letterList != null) {
            for (Message message : letterList) {
                if (hostHolder.getUser().getId() == message.getToId() && message.getStatus() == 0) {
                    ids.add(message.getId());
                }
            }
        }
        return ids;

    }

    //封装获取私信目标对象方法
    public User getLetterTraget(String conversationId){
        String[] ids = conversationId.split("_");
        int id0 = Integer.parseInt(ids[0]);
        int id1 = Integer.parseInt(ids[1]);

        if(hostHolder.getUser().getId() == id0){
            return userService.findUserById(id1);
        }else{
            return userService.findUserById(id0);
        }
    }

    //发送私信
    @PostMapping("/letter/send")
    @ResponseBody  //异步请求，增加@ResponseBody注解
    public String sendLetter(String toName,String content){
        //通过用户名查询用户
        User target = userService.findUserByName(toName);
        //查询后的异常处理
        if(target == null){
            return CommunityUtil.getJSONString(1,"目标用户不存在");  //返回json格式的字符串数据
        }

        //用户存在，构造message

        Message message = new Message();
        message.setFromId(hostHolder.getUser().getId());
        message.setToId(target.getId());
        //会话id
        if(message.getFromId() < message.getToId()){
            message.setConversationId(message.getFromId()+"_"+message.getToId());
        }else{
            message.setConversationId(message.getToId()+"_"+message.getFromId());
        }
        message.setContent(content);
        message.setCreateTime(new Date());

        messageService.addMessage(message);

        //如果没有报错返回状态码0,如果报错将来统一处理异常
        return CommunityUtil.getJSONString(0);

    }
}
